package model

import (
	"config-client-v1/init/global"
	j_log "config-client-v1/init/j-log"
	"fmt"
	"sync"
	"time"
)

type VarRecordQueueStu struct {
	Queue       chan *VarRecord
	Data        []*VarRecord
	mutex       sync.Mutex
	MaxWaitTime int
	PostDataNum int
}

type VarAlertQueueStu struct {
	Queue       chan *VarAlert
	Data        []*VarAlert
	mutex       sync.Mutex
	MaxWaitTime int
	PostDataNum int
}

var maxWaitTime, postDataNum int
var VarRecordQueue *VarRecordQueueStu
var VarAlertQueue *VarAlertQueueStu

func ReceiveVarRecord() {
	maxWaitTime, _ = global.AppConfig.Section("var_record").Key("max_wait_time").Int()
	postDataNum, _ = global.AppConfig.Section("var_record").Key("post_data_num").Int()
	VarRecordQueue = &VarRecordQueueStu{
		Queue:       make(chan *VarRecord, 10000),
		Data:        make([]*VarRecord, 0),
		mutex:       sync.Mutex{},
		MaxWaitTime: maxWaitTime,
		PostDataNum: postDataNum,
	}
	counter := 0
	var timer *time.Timer
	setTimerVarRecord(&counter, &timer)
	// 模拟接收数据
	for data := range VarRecordQueue.Queue {
		/*** 满足获取一定条数或者持续一段时间任意条件则存储数据*/
		VarRecordQueue.mutex.Lock()
		VarRecordQueue.Data = append(VarRecordQueue.Data, data)
		VarRecordQueue.mutex.Unlock()

		counter++
		// 每当计数器达到 n 时执行操作
		if counter == postDataNum {
			counter = 0 // 重置计数器
			if timer != nil {
				timer.Stop()                        // 取消定时器
				setTimerVarRecord(&counter, &timer) // 重置定时器
			}
			_ = insertVarRecord()
		}
	}
}

func insertVarRecord() (err error) {
	VarRecordQueue.mutex.Lock()
	defer VarRecordQueue.mutex.Unlock()
	defer func() {
		// 清空Data
		VarRecordQueue.Data = make([]*VarRecord, 0)
	}()
	if len(VarRecordQueue.Data) == 0 {
		return nil
	}

	//fmt.Println("--- affectRows: ", len(VarRecordQueue.Data), len(VarRecordQueue.Data))
	err = DB.Create(&VarRecordQueue.Data).Error
	if err != nil {
		fmt.Println("ReceiveData insert error: ", err)
		return
	}
	return nil
}
func setTimerVarRecord(counter *int, timer **time.Timer) {
	*timer = time.AfterFunc(time.Duration(maxWaitTime)*time.Second, func() {
		//fmt.Println("--- 超过" + strconv.Itoa(maxWaitTime) + "秒不足" + strconv.Itoa(postDataNum) + "条也处理; ")
		_ = insertVarRecord()
		*counter = 0 // 重置计数器
		setTimerVarRecord(counter, timer)
	})
}

// ReceiveVarAlert 同步接收保存
func ReceiveVarAlert() {
	VarAlertQueue = &VarAlertQueueStu{
		Queue:       make(chan *VarAlert, 10000),
		Data:        make([]*VarAlert, 0),
		mutex:       sync.Mutex{},
		MaxWaitTime: maxWaitTime,
		PostDataNum: postDataNum,
	}
	// 接收数据, 同步保存
	for data := range VarAlertQueue.Queue {
		if data.ID == 0 {
			err := DB.Create(data).Error
			if err != nil {
				j_log.LogError([]interface{}{"ReceiveVarAlert Create error: ", err.Error()})
			}
		} else {
			if data.IsRecovery == 1 {
				err := DB.Model(data).Where("id = ?", data.ID).Select("is_recovery", "recovery_time").Updates(data).Error
				if err != nil {
					j_log.LogError([]interface{}{"ReceiveVarAlert Update error: ", err.Error()})
				}
			} else {
				j_log.LogWarning([]interface{}{fmt.Sprintf("Exception: id=%d, is_recovery=%d", data.ID, data.IsRecovery)})
			}
		}
	}
}

// AsyncReceiveVarAlert 异步接收保存
func AsyncReceiveVarAlert() {
	maxWaitTime, _ = global.AppConfig.Section("var_record").Key("max_wait_time").Int()
	postDataNum, _ = global.AppConfig.Section("var_record").Key("post_data_num").Int()
	VarAlertQueue = &VarAlertQueueStu{
		Queue:       make(chan *VarAlert, 10000),
		Data:        make([]*VarAlert, 0),
		mutex:       sync.Mutex{},
		MaxWaitTime: maxWaitTime,
		PostDataNum: postDataNum,
	}
	counter := 0
	var timer *time.Timer
	setTimerVarAlert(&counter, &timer)
	// 模拟接收数据
	for data := range VarAlertQueue.Queue {
		/*** 满足获取一定条数或者持续一段时间任意条件则存储数据*/
		VarAlertQueue.mutex.Lock()
		VarAlertQueue.Data = append(VarAlertQueue.Data, data)
		VarAlertQueue.mutex.Unlock()

		counter++
		// 每当计数器达到 n 时执行操作
		if counter == postDataNum {
			counter = 0 // 重置计数器
			if timer != nil {
				timer.Stop()                       // 取消定时器
				setTimerVarAlert(&counter, &timer) // 重置定时器
			}
			_ = insertVarAlert()
		}
	}
}
func insertVarAlert() (err error) {
	VarAlertQueue.mutex.Lock()
	defer VarAlertQueue.mutex.Unlock()
	defer func() {
		// 清空Data
		VarAlertQueue.Data = make([]*VarAlert, 0)
	}()
	if len(VarAlertQueue.Data) == 0 {
		return nil
	}
	//fmt.Println("--- affectRows: ", len(VarAlertQueue.Data), len(VarAlertQueue.Data))
	err = DB.Create(&VarAlertQueue.Data).Error
	if err != nil {
		fmt.Println("ReceiveData insert error: ", err)
		return
	}
	return nil
}
func setTimerVarAlert(counter *int, timer **time.Timer) {
	*timer = time.AfterFunc(time.Duration(maxWaitTime)*time.Second, func() {
		//fmt.Println("--- 超过" + strconv.Itoa(maxWaitTime) + "秒不足" + strconv.Itoa(postDataNum) + "条也处理; ")
		_ = insertVarAlert()
		*counter = 0 // 重置计数器
		setTimerVarAlert(counter, timer)
	})
}
